/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.support.dev.order.notify;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import com.yanlight.support.http.AbstractRequest;
import com.yanlight.support.http.RequestBuilder;
import com.yanlight.util.DevSignatureUtil;
import com.yanlight.util.RandomStringUtil;

/**
 * 
 * @author haolw
 * @time 2018/02/25
 */
class DevOrderNotifyTask extends AbstractRequest<String> implements Delayed {
	private Map<String, String> notifyParams = new HashMap<>(8);
	private String notifyUrl;
	private String outTradeNo;
	private Integer payType;
	private Integer totalFee;
	private String payTime;
	private String secret;
	private int delaySecond;
	private long delayTime;
	private int loopCount;

	public String getNotifyUrl() {
		return notifyUrl;
	}

	public void setNotifyUrl(String notifyUrl) {
		this.notifyUrl = notifyUrl;
	}

	public String getOutTradeNo() {
		return outTradeNo;
	}

	public void setOutTradeNo(String outTradeNo) {
		this.outTradeNo = outTradeNo;
	}

	public Integer getPayType() {
		return payType;
	}

	public void setPayType(Integer payType) {
		this.payType = payType;
	}

	public Integer getTotalFee() {
		return totalFee;
	}

	public void setTotalFee(Integer totalFee) {
		this.totalFee = totalFee;
	}

	public String getPayTime() {
		return payTime;
	}

	public void setPayTime(String payTime) {
		this.payTime = payTime;
	}

	public String getSecret() {
		return secret;
	}

	public void setSecret(String secret) {
		this.secret = secret;
	}

	public int getDelaySecond() {
		return delaySecond;
	}

	public void setDelaySecond(int delaySecond) {
		this.delaySecond = delaySecond;
		this.delayTime = System.currentTimeMillis() + delaySecond * 1000;
	}

	public int getLoopCount() {
		return loopCount;
	}

	public void loop() {
		loopCount++;
		if (loopCount <= 3) {
			setDelaySecond(3);
		} else if (loopCount <= 5) {
			setDelaySecond(15);
		} else if (loopCount == 6) {
			setDelaySecond(30);
		} else if (loopCount == 7) {
			setDelaySecond(60);
		} else if (loopCount == 8) {
			setDelaySecond(180);
		} else if (loopCount == 9) {
			setDelaySecond(1800);
		} else {
			setDelaySecond(3600);
		}
	}

	@Override
	protected void execute(RequestBuilder builder) {
		buildNotifyParams();
		builder.addParams(notifyParams);
		builder.post().setUrl(notifyUrl);
	}

	private void buildNotifyParams() {
		if (this.loopCount < 1) {
			notifyParams.put("outTradeNo", outTradeNo);
			notifyParams.put("payType", String.valueOf(payType));
			notifyParams.put("totalFee", String.valueOf(totalFee));
			notifyParams.put("payTime", payTime);
			notifyParams.put("outTradeNo", outTradeNo);
			notifyParams.put("nonceStr", RandomStringUtil.randomAlphanumeric(32));
			String sign = DevSignatureUtil.sign(notifyParams, secret);
			notifyParams.put("sign", sign);
		}
	}

	@Override
	public int compareTo(Delayed o) {
		DevOrderNotifyTask task = (DevOrderNotifyTask) o;
		int diff = task.getDelaySecond() - this.getDelaySecond();
		if (diff > 0) {
			return -1;
		} else if (diff < 0) {
			return 1;
		} else {
			return 0;
		}
	}

	@Override
	public long getDelay(TimeUnit unit) {
		long duration = unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
		return duration;
	}

}
